package com.dragon.mmochat.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.model.MmochatNews;
import com.dragon.mmochat.model.enumType.MmochatQQNewsType;

//获取新闻rss
public class MmochatNewsService {
	private static Logger log = LoggerFactory
			.getLogger(MmochatNewsService.class);
	public static String qqNewsRssUrl1 = "http://news.qq.com/newssh/rss_newssh.xml";
	public static String qqNewsRssUrl2 = "http://news.qq.com/newsgn/rss_newsgn.xml";
	public static String qqNewsRssUrl3 = "http://news.qq.com/newsgj/rss_newswj.xml";

	public static ScheduledExecutorService updateNewsThread = Executors
			.newScheduledThreadPool(1);

	// 新闻正文内容超过多少长度，则不读取此条
	public static int newsContentLengthLimit = 6144;

	public static int aliveNewsNum = 30;// 最多显示的新闻条数
	// <MmochatQQNewsType,<id-->新闻>>
	public static Map<MmochatQQNewsType, Map<Integer, MmochatNews>> newsMap = new ConcurrentHashMap<MmochatQQNewsType, Map<Integer, MmochatNews>>();

	// 新闻正文内容标签ID
	public static String qqNewsContentId = "Cnt-Main-Article-QQ";
	
	//所有新闻总点击数
	public static int totalNewsHit = 0;

	public MmochatNewsService() {
		for (MmochatQQNewsType type : MmochatQQNewsType.values()) {
			Map<Integer, MmochatNews> news = new ConcurrentHashMap<Integer, MmochatNews>();
			newsMap.put(type, news);
		}
		updateNewsThread.scheduleWithFixedDelay(new updateNews(), 1, 10,
				TimeUnit.MINUTES);
	}

	class updateNews implements Runnable {
		@Override
		public void run() {
			try {
				if (!MmochatConstant.isNewsOpen) {
					return;
				}
				for (MmochatQQNewsType newsType : MmochatQQNewsType.values()) {
					try {
						getQQNews(newsType);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

				// 如果有效新闻数超过aliveNewsNum条
				for (Map<Integer, MmochatNews> subMap : newsMap.values()) {
					// 新闻数据超过3小时的则进行删除
					for (MmochatNews news : subMap.values()) {
						if (news.isTimeOut()) {
							subMap.remove(news.getId());
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 获取最新的新闻列表
	public static List<MmochatNews> getLatestNews(MmochatQQNewsType newsType) {
		Map<Integer, MmochatNews> subMap = newsMap.get(newsType);
		if (subMap == null) {
			return new ArrayList<MmochatNews>();
		}
		List<MmochatNews> list = new ArrayList<MmochatNews>(subMap.values());
		if (list.size() > 0) {
			Collections.sort(list);
			try {
				if (aliveNewsNum > 0) {
					return list.subList(0, Math.min(aliveNewsNum, list.size()));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	// 从qq获取新闻数据，并放入newsMap
	public void getQQNews(MmochatQQNewsType newsType) {
		try {
			log.debug("start get qq news");
			URL url = new URL(newsType.getUrl());
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(url.openStream());
			doc.getDocumentElement().normalize();
			NodeList listOfNews = doc.getElementsByTagName("item");
			log.debug("news num = " + listOfNews.getLength());

			Map<Integer, MmochatNews> curNewsMap = newsMap.get(newsType);

			for (int s = 0; s < listOfNews.getLength(); s++) {
				try {
					Node firstNpcNode = listOfNews.item(s);
					if (firstNpcNode.getNodeType() == Node.ELEMENT_NODE) {
						MmochatNews news = new MmochatNews();
						Element firstNewsElement = (Element) firstNpcNode;
						// 读取title
						{
							NodeList node = firstNewsElement
									.getElementsByTagName("title");
							String str = node.item(0).getChildNodes().item(0)
									.getNodeValue().trim();
							if (str != null) {
								boolean isNew = true;
								for (MmochatNews oldNews : curNewsMap.values()) {
									if (oldNews.getTitle().equals(str)) {
										// 已存在
										isNew = false;
										break;
									}
								}
								if (!isNew) {
									continue;
								}
								news.setTitle(str);
							}
						}
						// 读取link及正文
						{
							NodeList node = firstNewsElement
									.getElementsByTagName("link");
							String str = node.item(0).getChildNodes().item(0)
									.getNodeValue().trim();
							if (str != null) {
								String content = getQQNewsContent(str);
								if (content == null
										|| content.length() < 0
										|| content.length() > newsContentLengthLimit) {
									// 无数据或内容过长，则不读取
									continue;
								}
								news.setContent(content);
							}
						}
						// 读取pubDate
						{
							NodeList node = firstNewsElement
									.getElementsByTagName("pubDate");
							String str = node.item(0).getChildNodes().item(0)
									.getNodeValue().trim();
							if (str != null) {
								news.setPubTime(str);
							}
						}
						news.createId();
						curNewsMap.put(news.getId(), news);
					}
				} catch (Exception e) {
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 从新闻详情页面中读取正文内容
	public String getQQNewsContent(String urlInfo) {
		try {
			org.jsoup.nodes.Document doc = Jsoup.connect(urlInfo).get();
			if (doc != null) {
				org.jsoup.nodes.Element content = doc
						.getElementById(qqNewsContentId);
				if (content != null) {
					return content.text();
				}
			}
		} catch (SocketTimeoutException e) {
			log.error("read news time out,url:" + urlInfo);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
